/*******************************************************************************
 * Copyright (c) 2007 Pascal Essiembre.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Pascal Essiembre - initial API and implementation
 *    Alexej Strelzow - externalized IPropertiesSerializerConfig and 
 *    					IPropertiesDeserializerConfig for better reuse
 ******************************************************************************/
package org.eclipse.babel.editor.preferences;

import java.util.StringTokenizer;

import org.eclipse.babel.core.message.resource.ser.IPropertiesDeserializerConfig;
import org.eclipse.babel.core.message.resource.ser.IPropertiesSerializerConfig;
import org.eclipse.babel.editor.IMessagesEditorChangeListener;
import org.eclipse.babel.editor.builder.Builder;
import org.eclipse.babel.editor.builder.ToggleNatureAction;
import org.eclipse.babel.editor.internal.AbstractMessagesEditor;
import org.eclipse.babel.editor.plugin.MessagesEditorPlugin;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.text.StringMatcher;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;

/**
 * Messages Editor preferences.
 * 
 * @author Pascal Essiembre (pascal@essiembre.com)
 */
public final class MsgEditorPreferences implements IPropertyChangeListener {

    /**
     * the corresponding validation message with such a preference should not be
     * generated
     */
    public static final int VALIDATION_MESSAGE_IGNORE = 0;
    /**
     * the corresponding validation message with such a preference should
     * generate a marker with severity 'info'
     */
    public static final int VALIDATION_MESSAGE_INFO = 1;
    /**
     * the corresponding validation message with such a preference should
     * generate a marker with severity 'warning'
     */
    public static final int VALIDATION_MESSAGE_WARNING = 2;
    /**
     * the corresponding validation message with such a preference should
     * generate a marker with severity 'error'
     */
    public static final int VALIDATION_MESSAGE_ERROR = 3;

    /** Key group separator. */
    public static final String GROUP__LEVEL_SEPARATOR = "groupLevelSeparator"; //$NON-NLS-1$

    /** Should key tree be hiearchical by default. */
    public static final String KEY_TREE_HIERARCHICAL = "keyTreeHierarchical"; //$NON-NLS-1$
    /** Should key tree be expanded by default. */
    public static final String KEY_TREE_EXPANDED = "keyTreeExpanded"; //$NON-NLS-1$

    /** Should "Generated by" line be added to files. */
    public static final String SHOW_SUPPORT_ENABLED = "showSupportEnabled"; //$NON-NLS-1$

    /** Should Eclipse "nl" directory structure be supported. */
    public static final String NL_SUPPORT_ENABLED = "nLSupportEnabled"; //$NON-NLS-1$

    /** Should resources also be loaded from fragments. */
    public static final String SUPPORT_FRAGMENTS = "supportFragments"; //$NON-NLS-1$
    /**
     * Load only fragment resources when loading from fragments. The default
     * bundle is mostly located in the host plug-in.
     */
    public static final String LOADING_ONLY_FRAGMENT_RESOURCES = "loadingOnlyFragmentResources";

    /** Should tab characters be inserted when tab key pressed on text field. */
    public static final String FIELD_TAB_INSERTS = "fieldTabInserts"; //$NON-NLS-1$

    /** Should equal signs be aligned. */
    public static final String ALIGN_EQUALS_ENABLED = "alignEqualsEnabled"; //$NON-NLS-1$
    /** Should spaces be put around equal signs. */
    public static final String SPACES_AROUND_EQUALS_ENABLED = "spacesAroundEqualsEnabled"; //$NON-NLS-1$

    /** Should keys be grouped. */
    public static final String GROUP_KEYS_ENABLED = "groupKeysEnabled"; //$NON-NLS-1$
    /** How many level deep should keys be grouped. */
    public static final String GROUP_LEVEL_DEEP = "groupLevelDeep"; //$NON-NLS-1$
    /** How many line breaks between key groups. */
    public static final String GROUP_SEP_BLANK_LINE_COUNT = "groupSepBlankLineCount"; //$NON-NLS-1$
    /** Should equal signs be aligned within groups. */
    public static final String GROUP_ALIGN_EQUALS_ENABLED = "groupAlignEqualsEnabled"; //$NON-NLS-1$

    /** Should lines be wrapped. */
    public static final String WRAP_LINES_ENABLED = "wrapLinesEnabled"; //$NON-NLS-1$
    /** Maximum number of character after which we should wrap. */
    public static final String WRAP_LINE_LENGTH = "wrapLineLength"; //$NON-NLS-1$
    /** Align subsequent lines with equal signs. */
    public static final String WRAP_ALIGN_EQUALS_ENABLED = "wrapAlignEqualsEnabled"; //$NON-NLS-1$
    /** Number of spaces to indent subsequent lines. */
    public static final String WRAP_INDENT_LENGTH = "wrapIndentLength"; //$NON-NLS-1$

    /** Should unicode values be converted to their encoded equivalent. */
    public static final String UNICODE_ESCAPE_ENABLED = "unicodeEscapeEnabled"; //$NON-NLS-1$
    /** Should unicode values be converted to their encoded equivalent. */
    public static final String UNICODE_ESCAPE_UPPERCASE = "unicodeEscapeUppercase"; //$NON-NLS-1$
    /** Should encoded values be converted to their unicode equivalent. */
    public static final String UNICODE_UNESCAPE_ENABLED = "unicodeUnescapeEnabled"; //$NON-NLS-1$

    /** Impose a given new line type. */
    public static final String FORCE_NEW_LINE_TYPE = "forceNewLineType"; //$NON-NLS-1$
    /** How new lines are represented in resource bundle. */
    public static final String NEW_LINE_STYLE = "newLineStyle"; //$NON-NLS-1$
    /** Should new lines character produce a line break in properties files. */
    public static final String NEW_LINE_NICE = "newLineNice"; //$NON-NLS-1$

    /**
     * Report missing values with given level of reporting: IGNORE, INFO,
     * WARNING, ERROR.
     */
    public static final String REPORT_MISSING_VALUES_LEVEL = "detectMissingValuesLevel"; //$NON-NLS-1$
    /** Report duplicate values. */
    public static final String REPORT_DUPL_VALUES_LEVEL = "reportDuplicateValuesLevel"; //$NON-NLS-1$
    /** Report duplicate values. */
    public static final String REPORT_DUPL_VALUES_ONLY_IN_ROOT_LOCALE = "reportDuplicateValuesOnlyInRootLocale"; //$NON-NLS-1$
    /** Report similar values. */
    public static final String REPORT_SIM_VALUES_LEVEL = "reportSimilarValuesLevel"; //$NON-NLS-1$
    /** Report similar values: word compare. */
    public static final String REPORT_SIM_VALUES_WORD_COMPARE = "reportSimilarValuesWordCompare"; //$NON-NLS-1$
    /** Report similar values: levensthein distance. */
    public static final String REPORT_SIM_VALUES_LEVENSTHEIN = "reportSimilarValuesLevensthein"; //$NON-NLS-1$
    /** Report similar values: precision. */
    public static final String REPORT_SIM_VALUES_PRECISION = "reportSimilarValuesPrecision"; //$NON-NLS-1$

    /** Don't show the tree within the editor. */
    public static final String EDITOR_TREE_HIDDEN = "editorTreeHidden"; //$NON-NLS-1$

    /** Keep empty fields. */
    public static final String KEEP_EMPTY_FIELDS = "keepEmptyFields"; //$NON-NLS-1$

    /** Sort keys. */
    public static final String SORT_KEYS = "sortKeys"; //$NON-NLS-1$

    /** Display comment editor for default language. */
    public static final String DISPLAY_DEFAULT_COMMENT_FIELD = "displayCommentFieldNL"; //$NON-NLS-1$
    /** Display comment editor for all languages */
    public static final String DISPLAY_LANG_COMMENT_FIELDS = "displayLangCommentFieldsNL"; //$NON-NLS-1$

    /**
     * Locales filter and order defined as a comma separated list of string
     * matchers
     */
    public static final String FILTER_LOCALES_STRING_MATCHERS = "localesFilterStringMatchers";

    /**
     * When true the builder that validates translation files is automatically
     * added to java projects when the plugin is started or when a new project
     * is added.
     */
    public static final String ADD_MSG_EDITOR_BUILDER_TO_JAVA_PROJECTS = "addMsgEditorBuilderToJavaProjects";

    /**
     * holds what filter is activated. for the properties displayed in the
     * editor.
     */
    public static final String PROPERTIES_DISPLAYED_FILTER = "propertiesFilter";

    /**
     * true to enable the indexer false otherwise. the indexer is used to
     * generate list of suggestions in the translations. this is currently
     * experimental.
     */
    public static final String ENABLE_PROPERTIES_INDEXER = "enablePropertiesIndexer";

    /** MsgEditorPreferences. */
    private static final IPreferenceStore PREFS = MessagesEditorPlugin.getDefault().getPreferenceStore();

    private static final MsgEditorPreferences INSTANCE = new MsgEditorPreferences();

    private final IPropertiesSerializerConfig serializerConfig = new PropertiesSerializerConfig();

    private final IPropertiesDeserializerConfig deserializerConfig = new PropertiesDeserializerConfig();

    private StringMatcher[] cachedCompiledLocaleFilter;

    /**
     * Constructor.
     */
	private MsgEditorPreferences() {
        super();
    }

    public static MsgEditorPreferences getInstance() {
        return INSTANCE;
    }

    public IPropertiesSerializerConfig getSerializerConfig() {
        return serializerConfig;
    }

    public IPropertiesDeserializerConfig getDeserializerConfig() {
        return deserializerConfig;
    }

    /**
     * Gets whether pressing tab inserts a tab in a field.
     * 
     * @return <code>true</code> if pressing tab inserts a tab in a field
     */
    public boolean isFieldTabInserts() {
        return PREFS.getBoolean(FIELD_TAB_INSERTS);
    }

    /**
     * Gets whether key tree should be displayed in hiearchical way by default.
     * 
     * @return <code>true</code> if hierarchical
     */
    public boolean isKeyTreeHierarchical() {
        return PREFS.getBoolean(KEY_TREE_HIERARCHICAL);
    }

    /**
     * Gets whether key tree should be show expaned by default.
     * 
     * @return <code>true</code> if expanded
     */
    public boolean isKeyTreeExpanded() {
        return PREFS.getBoolean(KEY_TREE_EXPANDED);
    }

    /**
     * Gets whether to support Eclipse NL directory structure.
     * 
     * @return <code>true</code> if supported
     */
    public boolean isNLSupportEnabled() {
        return PREFS.getBoolean(NL_SUPPORT_ENABLED);
    }

    /**
     * Gets whether to support resources found in fragments.
     * 
     * @return <code>true</code> if supported
     */
    public boolean isLoadingOnlyFragmentResources() {
        return PREFS.getBoolean(LOADING_ONLY_FRAGMENT_RESOURCES);
    }

    /**
     * Gets whether to support resources found in fragments.
     * 
     * @return <code>true</code> if supported
     */
    public boolean getSupportFragments() {
        return PREFS.getBoolean(SUPPORT_FRAGMENTS);
    }

    // /**
    // * True iff the I18N editor page should contiain a comment field for the
    // * default language
    // *
    // * @return boolean
    // */
    // public static boolean getDisplayDefaultCommentField() {
    // return PREFS.getBoolean(DISPLAY_DEFAULT_COMMENT_FIELD);
    // }
    //
    // /**
    // * True iff the I18N editor page should contain a comment field for each
    // * individual language
    // *
    // * @return boolean
    // */
    // public static boolean getDisplayLangCommentFields() {
    // return PREFS.getBoolean(DISPLAY_LANG_COMMENT_FIELDS);
    // }
    //

    /**
     * @return the filter to apply on the displayed properties. One of the
     *         {@link IMessagesEditorChangeListener}.SHOW_* Byt default: show
     *         all.
     */
    public int getPropertiesFilter() {
        return PREFS.getInt(PROPERTIES_DISPLAYED_FILTER);
    }

    /**
     * @param filter
     *            The filter to apply on the displayed properties. One of the
     *            {@link IMessagesEditorChangeListener}.SHOW_*
     */
    public void setPropertiesFilter(int filter) {
        PREFS.setValue(PROPERTIES_DISPLAYED_FILTER, filter);
    }

    /**
     * Gets whether we want to overwrite system (or Eclipse) default new line
     * type when generating file.
     * 
     * @return <code>true</code> if overwriting
     */
    public boolean getForceNewLineType() {
        return PREFS.getBoolean(FORCE_NEW_LINE_TYPE);
    }

    /**
     * Gets whether to report keys with missing values.
     * 
     * @return <code>true</code> if reporting
     */
    public boolean getReportMissingValues() {
        return PREFS.getInt(REPORT_MISSING_VALUES_LEVEL) != VALIDATION_MESSAGE_IGNORE;
        // return PREFS.getBoolean(REPORT_MISSING_VALUES);
    }

    /**
     * Returns the level of reporting for missing values.
     * 
     * @return VALIDATION_MESSAGE_IGNORE or VALIDATION_MESSAGE_INFO or
     *         VALIDATION_MESSAGE_WARNING or VALIDATION_MESSAGE_ERROR.
     */
    public int getReportMissingValuesLevel() {
        return PREFS.getInt(REPORT_MISSING_VALUES_LEVEL);
    }

    /**
     * Gets whether to report keys with duplicate values.
     * 
     * @return <code>true</code> if reporting
     */
    public boolean getReportDuplicateValues() {
        return PREFS.getInt(REPORT_DUPL_VALUES_LEVEL) != VALIDATION_MESSAGE_IGNORE;
    }

    /**
     * Returns the level of reporting for duplicate values.
     * 
     * @return VALIDATION_MESSAGE_IGNORE or VALIDATION_MESSAGE_INFO or
     *         VALIDATION_MESSAGE_WARNING or VALIDATION_MESSAGE_ERROR.
     */
    public int getReportDuplicateValuesLevel() {
        return PREFS.getInt(REPORT_DUPL_VALUES_LEVEL);
    }

    /**
     * Gets whether to report keys with duplicate values.
     * 
     * @return <code>true</code> if reporting duplicate is applied only for the
     *         root locale (aka default properties file.)
     */
    public boolean getReportDuplicateValuesOnlyInRootLocales() {
        return PREFS.getBoolean(REPORT_DUPL_VALUES_ONLY_IN_ROOT_LOCALE);
    }

    /**
     * Gets whether to report keys with similar values.
     * 
     * @return <code>true</code> if reporting
     */
    public boolean getReportSimilarValues() {
        return PREFS.getInt(REPORT_SIM_VALUES_LEVEL) != VALIDATION_MESSAGE_IGNORE;
    }

    /**
     * Returns the level of reporting for similar values.
     * 
     * @return VALIDATION_MESSAGE_IGNORE or VALIDATION_MESSAGE_INFO or
     *         VALIDATION_MESSAGE_WARNING or VALIDATION_MESSAGE_ERROR.
     */
    public int getReportSimilarValuesLevel() {
        return PREFS.getInt(REPORT_SIM_VALUES_LEVEL);
    }

    /**
     * Gets whether to use the "word compare" method when reporting similar
     * values.
     * 
     * @return <code>true</code> if using "word compare" method
     */
    public boolean getReportSimilarValuesWordCompare() {
        return PREFS.getBoolean(REPORT_SIM_VALUES_WORD_COMPARE);
    }

    /**
     * Gets whether to use the Levensthein method when reporting similar values.
     * 
     * @return <code>true</code> if using Levensthein method
     */
    public boolean getReportSimilarValuesLevensthein() {
        return PREFS.getBoolean(REPORT_SIM_VALUES_LEVENSTHEIN);
    }

    /**
     * Gets the minimum precision level to use for determining when to report
     * similarities.
     * 
     * @return precision
     */
    public double getReportSimilarValuesPrecision() {
        return PREFS.getDouble(REPORT_SIM_VALUES_PRECISION);
    }

    /**
     * Gets whether a tree shall be displayed within the editor or not.
     * 
     * @return <code>true</code> A tree shall not be displayed.
     */
    public boolean isEditorTreeHidden() {
        return PREFS.getBoolean(EDITOR_TREE_HIDDEN);
    }

    /**
     * Gets whether to keep empty fields.
     * 
     * @return <code>true</code> if empty fields are to be kept.
     */
    public boolean getKeepEmptyFields() {
        return PREFS.getBoolean(KEEP_EMPTY_FIELDS);
    }

    /**
     * @return a comma separated list of locales-string-matchers.
     *         <p>
     *         Note: StringMatcher is an internal API duplicated in many
     *         different places of eclipse. The only project that decided to
     *         make it public is GMF (org.eclipse.gmf.runtime.common.core.util)
     *         Although they have been request to make it public since 2001:
     *         http://dev.eclipse.org/newslists/news.eclipse.tools/msg00666.html
     *         </p>
     *         <p>
     *         We choose org.eclipse.ui.internal.misc in the
     *         org.eclipse.ui.workbench plugin as it is part of RCP; the most
     *         common one.
     *         </p>
     * @see org.eclipse.ui.internal.misc.StringMatcher
     */
    public String getFilterLocalesStringMatcher() {
        return PREFS.getString(FILTER_LOCALES_STRING_MATCHERS);
    }

    /**
     * @return The StringMatchers compiled from #getFilterLocalesStringMatcher()
     */
    public synchronized StringMatcher[] getFilterLocalesStringMatchers() {
        if (cachedCompiledLocaleFilter != null) {
            return cachedCompiledLocaleFilter;
        }

        String pref = PREFS.getString(FILTER_LOCALES_STRING_MATCHERS);
        StringTokenizer tokenizer = new StringTokenizer(pref, ";, ", false);
        cachedCompiledLocaleFilter = new StringMatcher[tokenizer.countTokens()];
        int ii = 0;
        while (tokenizer.hasMoreTokens()) {
            StringMatcher pattern = new StringMatcher(tokenizer.nextToken()
                    .trim(), true, false);
            cachedCompiledLocaleFilter[ii] = pattern;
            ii++;
        }
        return cachedCompiledLocaleFilter;
    }

    /**
     * Gets whether the rbe nature and rbe builder are automatically setup on
     * java projects in the workspace.
     * 
     * @return <code>true</code> Setup automatically the rbe builder on java
     *         projects.
     */
    public boolean isBuilderSetupAutomatically() {
        return PREFS.getBoolean(ADD_MSG_EDITOR_BUILDER_TO_JAVA_PROJECTS);
    }

    /**
     * Notified when the value of the filter locales preferences changes.
     * 
     * @param event
     *            the property change event object describing which property
     *            changed and how
     */
    public void propertyChange(PropertyChangeEvent event) {
        if (FILTER_LOCALES_STRING_MATCHERS.equals(event.getProperty())) {
            onLocalFilterChange();
        } else if (ADD_MSG_EDITOR_BUILDER_TO_JAVA_PROJECTS.equals(event
                .getProperty())) {
            onAddValidationBuilderChange();
        }
    }

    /**
     * Called when the locales filter value is changed.
     * <p>
     * Takes care of reloading the opened editors and calling the full-build of
     * the rbeBuilder on all project that use it.
     * </p>
     */
    private void onLocalFilterChange() {
        cachedCompiledLocaleFilter = null;

        // first: refresh the editors.
        // look at the opened editors and reload them if possible
        // otherwise, save them, close them and re-open them.
        IWorkbenchPage[] pages = PlatformUI.getWorkbench()
                .getActiveWorkbenchWindow().getPages();
        for (int i = 0; i < pages.length; i++) {
            IEditorReference[] edRefs = pages[i].getEditorReferences();
            for (int j = 0; j < edRefs.length; j++) {
                IEditorReference ref = edRefs[j];
                IEditorPart edPart = ref.getEditor(false);
                if (edPart != null && edPart instanceof AbstractMessagesEditor) {
                    // the editor was loaded. reload it:
                    AbstractMessagesEditor meToReload = (AbstractMessagesEditor) edPart;
                    meToReload.reloadDisplayedContents();
                }
            }
        }

        // second: clean and build all the projects that have the rbe builder.
        // Calls the builder for a clean and build on all projects of the
        // workspace.
        try {
            IProject[] projs = ResourcesPlugin.getWorkspace().getRoot()
                    .getProjects();
            for (int i = 0; i < projs.length; i++) {
                if (projs[i].isAccessible()) {
                    ICommand[] builders = projs[i].getDescription()
                            .getBuildSpec();
                    for (int j = 0; j < builders.length; j++) {
                        if (Builder.BUILDER_ID.equals(builders[j]
                                .getBuilderName())) {
                            projs[i].build(
                                    IncrementalProjectBuilder.FULL_BUILD,
                                    Builder.BUILDER_ID, null,
                                    new NullProgressMonitor());
                            break;
                        }
                    }
                }
            }
        } catch (CoreException ce) {
            IStatus status = new Status(IStatus.ERROR,
                    MessagesEditorPlugin.PLUGIN_ID, IStatus.OK,
                    ce.getMessage(), ce);
            MessagesEditorPlugin.getDefault().getLog().log(status);
        }
    }

    /**
     * Called when the value of the setting up automatically the validation
     * builder to projects is changed.
     * <p>
     * When changed to true, call the static method that goes through the
     * projects accessible in the workspace and if they have a java nature, make
     * sure they also have the rbe nature and rbe builder.
     * </p>
     * <p>
     * When changed to false, make a dialog offering the user to remove all
     * setup builders from the projects where it can be found.
     * </p>
     */
    private void onAddValidationBuilderChange() {
        if (isBuilderSetupAutomatically()) {
            ToggleNatureAction.addOrRemoveNatureOnAllJavaProjects(true);
        } else {
            boolean res = MessageDialog
                    .openQuestion(
                            PlatformUI.getWorkbench().getDisplay()
                                    .getActiveShell(),
                            MessagesEditorPlugin
                                    .getString("prefs.removeAlreadyInstalledValidators.title"),
                            MessagesEditorPlugin
                                    .getString("prefs.removeAlreadyInstalledValidators.text"));
            if (res) {
                ToggleNatureAction.addOrRemoveNatureOnAllJavaProjects(false);
            }
        }
    }

    // ###########################################################################################
    // ###############################PropertiesSerializerConfig##################################
    // ###########################################################################################

    // /**
    // * Gets whether to escape unicode characters when generating file.
    // * @return <code>true</code> if escaping
    // */
    // public boolean isUnicodeEscapeEnabled() {
    // return PREFS.getBoolean(UNICODE_ESCAPE_ENABLED);
    // }
    //
    // /**
    // * Gets the new line type to use when overwriting system (or Eclipse)
    // * default new line type when generating file. Use constants to this
    // * effect.
    // * @return new line type
    // */
    // public int getNewLineStyle() {
    // return PREFS.getInt(NEW_LINE_STYLE);
    // }
    //
    // /**
    // * Gets how many blank lines should separate groups when generating file.
    // * @return how many blank lines between groups
    // */
    // public int getGroupSepBlankLineCount() {
    // return PREFS.getInt(GROUP_SEP_BLANK_LINE_COUNT);
    // }
    //
    // /**
    // * Gets whether to print "Generated By..." comment when generating file.
    // * @return <code>true</code> if we print it
    // */
    // public boolean isShowSupportEnabled() {
    // return PREFS.getBoolean(SHOW_SUPPORT_ENABLED);
    // }
    //
    // /**
    // * Gets whether keys should be grouped when generating file.
    // * @return <code>true</code> if keys should be grouped
    // */
    // public boolean isGroupKeysEnabled() {
    // return PREFS.getBoolean(GROUP_KEYS_ENABLED);
    // }
    //
    // /**
    // * Gets whether escaped unicode "alpha" characters should be uppercase
    // * when generating file.
    // * @return <code>true</code> if uppercase
    // */
    // public boolean isUnicodeEscapeUppercase() {
    // return PREFS.getBoolean(UNICODE_ESCAPE_UPPERCASE);
    // }
    //
    // /**
    // * Gets the number of character after which lines should be wrapped when
    // * generating file.
    // * @return number of characters
    // */
    // public int getWrapLineLength() {
    // return PREFS.getInt(WRAP_LINE_LENGTH);
    // }
    //
    // /**
    // * Gets whether lines should be wrapped if too big when generating file.
    // * @return <code>true</code> if wrapped
    // */
    // public boolean isWrapLinesEnabled() {
    // return PREFS.getBoolean(WRAP_LINES_ENABLED);
    // }
    //
    // /**
    // * Gets whether wrapped lines should be aligned with equal sign when
    // * generating file.
    // * @return <code>true</code> if aligned
    // */
    // public boolean isWrapAlignEqualsEnabled() {
    // return PREFS.getBoolean(WRAP_ALIGN_EQUALS_ENABLED);
    // }
    //
    // /**
    // * Gets the number of spaces to use for indentation of wrapped lines when
    // * generating file.
    // * @return number of spaces
    // */
    // public int getWrapIndentLength() {
    // return PREFS.getInt(WRAP_INDENT_LENGTH);
    // }
    //
    // /**
    // * Gets whether there should be spaces around equals signs when generating
    // * file.
    // * @return <code>true</code> there if should be spaces around equals signs
    // */
    // public boolean isSpacesAroundEqualsEnabled() {
    // return PREFS.getBoolean(SPACES_AROUND_EQUALS_ENABLED);
    // }
    //
    // /**
    // * Gets whether new lines are escaped or printed as is when generating
    // file.
    // * @return <code>true</code> if printed as is.
    // */
    // public boolean isNewLineNice() {
    // return PREFS.getBoolean(NEW_LINE_NICE);
    // }
    //
    // /**
    // * Gets how many level deep keys should be grouped when generating file.
    // * @return how many level deep
    // */
    // public int getGroupLevelDepth() {
    // return PREFS.getInt(GROUP_LEVEL_DEEP);
    // }
    //
    // /**
    // * Gets key group separator.
    // * @return key group separator.
    // */
    // public String getGroupLevelSeparator() {
    // return PREFS.getString(GROUP__LEVEL_SEPARATOR);
    // }
    //
    // /**
    // * Gets whether equals signs should be aligned when generating file.
    // * @return <code>true</code> if equals signs should be aligned
    // */
    // public boolean isAlignEqualsEnabled() {
    // return PREFS.getBoolean(ALIGN_EQUALS_ENABLED);
    // }
    //
    // /**
    // * Gets whether equal signs should be aligned within each groups when
    // * generating file.
    // * @return <code>true</code> if equal signs should be aligned within
    // groups
    // */
    // public boolean isGroupAlignEqualsEnabled() {
    // return PREFS.getBoolean(GROUP_ALIGN_EQUALS_ENABLED);
    // }
    //
    // /**
    // * Gets whether to sort keys upon serializing them.
    // * @return <code>true</code> if keys are to be sorted.
    // */
    // public boolean isKeySortingEnabled() {
    // return PREFS.getBoolean(SORT_KEYS);
    // }

    // ###########################################################################################
    // ###############################PropertiesSerializerConfig##################################
    // ###########################################################################################

    // /**
    // * Gets whether to convert encoded strings to unicode characters when
    // * reading file.
    // * @return <code>true</code> if converting
    // */
    // public boolean isUnicodeUnescapeEnabled() {
    // return PREFS.getBoolean(UNICODE_UNESCAPE_ENABLED);
    // }

}
